package com.zdltech.lightappupdatelib.utils;

import android.support.annotation.NonNull;

import com.zdltech.lightappupdatelib.net.HttpManager;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

/**
 * HttpUTLConnect工具类
 *
 * @ Des
 * @ Author jason
 */

public class HttpURLConnectUtils {

    /**
     * 多文件上传的方法
     *
     * @param actionUrl：上传的路径
     * @param uploadFilePaths：需要上传的文件路径，数组
     * @return
     *
     * @Demo uploadFile("http://127.0.0.1:8080/image/image.do",new String[] { "/Users//H__D/Desktop//1.png","//Users/H__D/Desktop/2.png" })
     */
    @SuppressWarnings("finally")
    public static String uploadFile(String actionUrl, String[] uploadFilePaths) {
        String end = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";

        DataOutputStream ds = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        StringBuffer resultBuffer = new StringBuffer();
        String tempLine = null;

        try {
            // 统一资源
            URL url = new URL(actionUrl);
            // 连接类的父类，抽象类
            URLConnection urlConnection = url.openConnection();
            // http的连接类
            HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;

            // 设置是否从httpUrlConnection读入，默认情况下是true;
            httpURLConnection.setDoInput(true);
            // 设置是否向httpUrlConnection输出
            httpURLConnection.setDoOutput(true);
            // Post 请求不能使用缓存
            httpURLConnection.setUseCaches(false);
            // 设定请求的方法，默认是GET
            httpURLConnection.setRequestMethod("POST");
            // 设置字符编码连接参数
            httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
            // 设置字符编码
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            // 设置请求内容类型
            httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

            // 设置DataOutputStream
            ds = new DataOutputStream(httpURLConnection.getOutputStream());
            for (int i = 0; i < uploadFilePaths.length; i++) {
                String uploadFile = uploadFilePaths[i];
                String filename = uploadFile.substring(uploadFile.lastIndexOf("//") + 1);
                ds.writeBytes(twoHyphens + boundary + end);
                ds.writeBytes("Content-Disposition: form-data; " + "name=\"file" + i + "\";filename=\"" + filename
                        + "\"" + end);
                ds.writeBytes(end);
                FileInputStream fStream = new FileInputStream(uploadFile);
                int bufferSize = 1024;
                byte[] buffer = new byte[bufferSize];
                int length = -1;
                while ((length = fStream.read(buffer)) != -1) {
                    ds.write(buffer, 0, length);
                }
                ds.writeBytes(end);
                /* close streams */
                fStream.close();
            }
            ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
            /* close streams */
            ds.flush();
            if (httpURLConnection.getResponseCode() >= 300) {
                throw new Exception(
                        "HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
            }

            if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                inputStream = httpURLConnection.getInputStream();
                inputStreamReader = new InputStreamReader(inputStream);
                reader = new BufferedReader(inputStreamReader);
                tempLine = null;
                resultBuffer = new StringBuffer();
                while ((tempLine = reader.readLine()) != null) {
                    resultBuffer.append(tempLine);
                    resultBuffer.append("\n");
                }
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (ds != null) {
                try {
                    ds.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

            return resultBuffer.toString();
        }
    }

    /**
     * @param urlPath     下载路径
     * @param downloadDir 下载存放目录
     * @return 返回下载文件
     * @Demo  downloadFile("http://localhost:8080/images/1467523487190.png", "/Users/H__D/Desktop");
     */
    public static File downloadFile(String urlPath, String downloadDir, HttpManager.FileCallback callback) {
        return downloadFile(urlPath,downloadDir,null,callback);
    }

    /**
     *
     * @param urlPath 下载路径
     * @param downloadDir 下载存放目录
     * @param fileName 文件名称
     * @param callback
     * @return
     */
    public static File downloadFile(String urlPath, String downloadDir,String fileName, HttpManager.FileCallback callback) {
        File file = null;
        try {
            // 统一资源
            URL url = new URL(urlPath);
            // 连接类的父类，抽象类
            URLConnection urlConnection = url.openConnection();
            // http的连接类
            HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
            // 设定请求的方法，默认是GET
            httpURLConnection.setRequestMethod("GET");
            // 设置字符编码
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            // 打开到此 URL 引用的资源的通信链接（如果尚未建立这样的连接）。
            httpURLConnection.connect();

            // 文件大小
            int fileLength = httpURLConnection.getContentLength();

            String fileFullName = fileName;
            // 文件名
            if (fileFullName==null){
                 String filePathUrl = httpURLConnection.getURL().getFile();
                 fileFullName = filePathUrl.substring(filePathUrl.lastIndexOf(File.separatorChar) + 1);
            }
            System.out.println("file length---->" + fileLength);
            BufferedInputStream bin = new BufferedInputStream(httpURLConnection.getInputStream());
            String path = downloadDir + File.separatorChar + fileFullName;
            file = new File(path);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            OutputStream out = new FileOutputStream(file);
            int size = 0;
            int len = 0;
            byte[] buf = new byte[1024];
            while ((size = bin.read(buf)) != -1) {
                len += size;
                out.write(buf, 0, size);
                if (callback!=null){
                    callback.onProgress(len,fileLength);
                }
                // 打印下载百分比
                // System.out.println("下载了-------> " + len * 100 / fileLength +
                // "%\n");
            }
            bin.close();
            out.close();
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            if (callback!=null){
                callback.onError(e.getMessage());
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            if (callback!=null){
                callback.onError(e.getMessage());
            }
        } finally {
            if (callback!=null){
                callback.onResponse(file);
            }
            return file;
        }

    }

    /**
     * @param urlPath     下载路径
     * @param downloadDir 下载存放目录
     * @param start 可变参数，断点下载的开始和结束位置
     * @return 返回下载文件
     * @Demo  downloadFile("http://localhost:8080/images/1467523487190.png", "/Users/H__D/Desktop");
     */
    public static File downloadFile(String urlPath, String downloadDir, HttpManager.FileCallback callback,long... start) {
        File file = null;
        try {
            RandomAccessFile access = null;
            // 统一资源
            URL url = new URL(urlPath);
            // 连接类的父类，抽象类
            URLConnection urlConnection = url.openConnection();
            // http的连接类
            HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
            // 设定请求的方法，默认是GET
            httpURLConnection.setRequestMethod("GET");
            // 设置字符编码
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            // 设置字符编码连接参数
            httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
            // 设置断点续传的开始位置
            httpURLConnection.setRequestProperty("Range", "bytes=" + start[0] + "-"+start[1]);
            // 打开到此 URL 引用的资源的通信链接（如果尚未建立这样的连接）。
            httpURLConnection.connect();

            // 文件大小
            int fileLength = httpURLConnection.getContentLength();

            // 文件名
            String filePathUrl = httpURLConnection.getURL().getFile();
            String fileFullName = filePathUrl.substring(filePathUrl.lastIndexOf(File.separatorChar) + 1);

            System.out.println("file length---->" + fileLength);

            BufferedInputStream bin = new BufferedInputStream(httpURLConnection.getInputStream());

            String path = downloadDir + File.separatorChar + fileFullName;

            file = new File(path);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            access = new RandomAccessFile(path,"rw");
            access.seek(start[0]);
            int size = 0;
            int len = 0;
            byte[] buf = new byte[1024];
            while ((size = bin.read(buf)) != -1) {
                len += size;
                access.write(buf, 0, size);
                if (callback!=null){
                    callback.onProgress(len,fileLength);
                }
            }
            bin.close();
            if (access!=null){
                access.close();
            }
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            if (callback!=null){
                callback.onError(e.getMessage());
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            if (callback!=null){
                callback.onError(e.getMessage());
            }
        } finally {
            if (callback!=null){
                callback.onResponse(file);
            }
            return file;
        }
    }

    public static File downloadFile(String urlPath, String downloadDir,String fileName, HttpManager.FileCallback callback,long... start) {
        File file = null;
        try {
            RandomAccessFile access = null;
            // 统一资源
            URL url = new URL(urlPath);
            // 连接类的父类，抽象类
            URLConnection urlConnection = url.openConnection();
            // http的连接类
            HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
            // 设定请求的方法，默认是GET
            httpURLConnection.setRequestMethod("GET");
            // 设置字符编码
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            // 设置字符编码连接参数
            httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
            // 设置断点续传的开始位置
            httpURLConnection.setRequestProperty("Range", "bytes=" + start[0] + "-"+start[1]);
            // 打开到此 URL 引用的资源的通信链接（如果尚未建立这样的连接）。
            httpURLConnection.connect();
            // 文件大小
            int fileLength = httpURLConnection.getContentLength();

            // 文件名
            String fileFullName=fileName;
            if (fileFullName==null){
                String filePathUrl = httpURLConnection.getURL().getFile();
                fileFullName = filePathUrl.substring(filePathUrl.lastIndexOf(File.separatorChar) + 1);
            }
            System.out.println("file length---->" + fileLength);

            BufferedInputStream bin = new BufferedInputStream(httpURLConnection.getInputStream());

            String path = downloadDir + File.separatorChar + fileFullName;

            file = new File(path);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            access = new RandomAccessFile(path,"rw");
            access.seek(start[0]);
            int size = 0;
            int len = 0;
            byte[] buf = new byte[1024];
            while ((size = bin.read(buf)) != -1) {
                len += size;
                access.write(buf, 0, size);
                if (callback!=null){
                    callback.onProgress(len,fileLength);
                }
            }
            bin.close();
            if (access!=null){
                access.close();
            }
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            if (callback!=null){
                callback.onError(e.getMessage());
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            if (callback!=null){
                callback.onError(e.getMessage());
            }
        } finally {
            if (callback!=null){
                callback.onResponse(file);
            }
            return file;
        }

    }

    /**
     * Get请求
     * @param url
     * @param callBack
     */
    public static void get(@NonNull  String url,  @NonNull HttpManager.Callback callBack){
        LogUtils.e("url="+url);
        request(url, new HashMap<String, String>(), false, callBack);
    }


    /**
     * GET 请求
     * @param url
     * @param params
     * @param callBack
     */
    public static void get(@NonNull String url,  @NonNull Map<String, String> params,  @NonNull HttpManager.Callback callBack){
        LogUtils.e("url="+url+",params="+params.toString());
        request(url, params, false, callBack);
    }


    /**
     * POST请求
     * @param url
     * @param params
     * @param callBack
     */
    public static void post(@NonNull  String url,  @NonNull Map<String, String> params,  @NonNull HttpManager.Callback callBack){
        request(url, params, true, callBack);
    }


    /**
     * 网络请求封装
     *
     * @param urlPath
     * @param params
     * @param isPost
     * @param callback
     */
    private static void request(String urlPath, Map<String, String> params, boolean isPost, HttpManager.Callback callback) {
        try {
            String mPath = urlPath;
            if (!isPost) {//如果是Get请求拼接参数到url
                 mPath=mPath+"?";
                for (String key : params.keySet()) {
                    mPath += key + "=" + params.get(key) + "&";
                }
            }
            URL url = new URL(mPath.trim());
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setConnectTimeout(30000);//连接超时 单位毫秒
            httpURLConnection.setReadTimeout(20000);//读取超时 单位毫秒
            httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            if (isPost) {
                httpURLConnection.setRequestMethod("POST");// 提交模式
                // 发送POST请求必须设置如下两行
                httpURLConnection.setDoOutput(true);
                httpURLConnection.setDoInput(true);
                // 获取URLConnection对象对应的输出流
                PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
                // 发送请求参数
                // POST的请求参数写在正文中  post的参数 xx=xx&yy=yy
                for (String key : params.keySet()) {
                    printWriter.write(key + "=" + params.get(key) + "&");
                }
                // flush输出流的缓冲
                printWriter.flush();
                printWriter.close();
            } else {
                httpURLConnection.setRequestMethod("GET");// 提交模式
                //Get请求不需要DoOutPut
                httpURLConnection.setDoOutput(false);
                httpURLConnection.setDoInput(true);
                httpURLConnection.connect();
            }

            //开始获取数据
            BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            int len;
            byte[] arr = new byte[1024];
            while ((len = bis.read(arr)) != -1) {
                bos.write(arr, 0, len);
                bos.flush();
            }
            bos.close();
            bis.close();

            int responseCode = httpURLConnection.getResponseCode();
            if (responseCode==HttpURLConnection.HTTP_OK){
                if (callback != null) {
                    callback.onResponse(bos.toString("utf-8"));
                }
            }else{
                if (callback != null) {
                    callback.onError("服务器返回异常：异常码为："+responseCode+",错误信息为："+bos.toString("utf-8"));
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            if (callback != null) {
                callback.onError(e.getMessage());
            }
        }
    }
}
